package net.xdclass.order.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.common.JsonData;
import net.xdclass.common.constant.Cons;
import net.xdclass.order.config.AliPayConfig;
import net.xdclass.order.enums.ProductOrderPayTypeEnum;
import net.xdclass.order.service.ProductOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 支付回调
 */
@Slf4j
@Controller
@RequestMapping("/api/callback/order/v1")
public class CallbackController {

    @Autowired
    private ProductOrderService productOrderService;

    /**
     * 支付宝支付回调
     * @param request
     * @param response
     * @return
     */
    @PostMapping("/alipay")
    public String callback(HttpServletRequest request, HttpServletResponse response){
        Map<String, String> params = getParams(request);
        //验签方法
        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.CHARSET, AliPayConfig.SIGN_TYPE);
            if(signVerified){
                JsonData jsonData = productOrderService.handleOrderCallback(ProductOrderPayTypeEnum.ALIPAY, params);
                if (Cons.SUCCESS.equals(jsonData.getCode())){
                    // 需要返回支付宝 success，否则会重复通知8次，然后认为交易失败
                    return "success";
                }
            }
        } catch (AlipayApiException e) {
            log.warn("支付宝支付回调验签失败【{}】", e.getErrMsg());
        }
        return "fail";
    }


    /**
     * 将request中的参数转换成Map
     * @param request
     * @return
     */
    private static Map<String, String> getParams(HttpServletRequest request) {
        Map<String, String> paramsMap = new HashMap<>(16);
        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int size = values.length;
            if (size == 1) {
                paramsMap.put(name, values[0]);
            } else {
                paramsMap.put(name, "");
            }
        }
        System.out.println(paramsMap);
        return paramsMap;
    }

}
